<template>
  <t-select
    ref="selectRef"
    v-model="modelValue"
    placeholder="请选择图标"
    :popup-props="{ overlayInnerStyle: { width: '400px' } }"
  >
    <t-option v-for="item in options" :key="item.stem" :value="item.stem" class="icon-select-option">
      <div>
        <component :is="item.component" />
      </div>
    </t-option>

    <template #valueDisplay>
      <component
        :is="selectedIcon"
        :style="{
          marginRight: '8px',
        }"
      />
      {{ modelValue }}

      <span v-show="!modelValue" :style="{ color: 'var(--td-text-color-disabled)' }">
        {{ selectRef?.placeholder }}
      </span>
    </template>
  </t-select>
</template>

<script lang="ts" setup>
import { manifest } from 'tdesign-icons-vue-next';
import { Select } from 'tdesign-vue-next';
import { computed, onMounted, ref, shallowRef, useTemplateRef } from 'vue';

const modelValue = defineModel<string>();

type TDSelectType = InstanceType<typeof Select>['$props'];

const selectRef = useTemplateRef<TDSelectType>('selectRef');

// vite 3+ support dynamic import from node_modules
const iconsPath = import.meta.glob('../../../../node_modules/tdesign-icons-vue-next/esm/components/*.js');

// 动态从包内引入单个Icon
async function getMenuIcon(iconName: string) {
  const RenderIcon = iconsPath[`../../../../node_modules/tdesign-icons-vue-next/esm/components/${iconName}.js`];
  const Icon = await RenderIcon();
  // @ts-ignore 暂未找到对应 ts 类型
  return shallowRef(Icon.default);
}

// 获取全部图标的列表
const options = ref([]);

// 当前选中的图标
const selectedIcon = computed(() => {
  const selectedOption = options.value.find((item) => item.stem === modelValue.value);
  return selectedOption ? selectedOption.component : null;
});

onMounted(async () => {
  options.value = await Promise.all(
    manifest.map(async (item) => ({
      stem: item.stem,
      icon: item.icon,
      component: await getMenuIcon(item.stem),
    })),
  );
});
</script>

<style lang="less" scoped>
:global(.icon-select-option) {
  display: inline-block;
  font-size: 20px;
  padding: 4px;
}
</style>
